﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Prob_Distributions_ClassLibrary;

namespace colas
{
    class EventoLlegadaCliente:IEvento
    {
        
        private double promedio;
        private double desviacionEstandar;
        private double tCompraTicket;
        private double tUtilizacionMesa;
        private double tAdicionalUtilizacionMesa;

        public EventoLlegadaCliente(double promedio, double desviacionEstandar, double tCompraTicket, double tUtilizacionMesa, double tAdicionalUtilizacionMesa)
        {
            this.promedio = promedio;
            this.desviacionEstandar = desviacionEstandar;
            this.tCompraTicket = tCompraTicket;
            this.tUtilizacionMesa=tUtilizacionMesa;
            this.tAdicionalUtilizacionMesa = tAdicionalUtilizacionMesa;
        }
        
        public gridline llenarLinea(gridline linea_anterior)
        {
            gridline linea=new gridline(linea_anterior);
            linea.Reloj = linea_anterior.proxima_llegada_cliente;
            linea.evento = (int)Utils.eventos.LLEGADA_CLIENTE;            
            generarProximaLlegada(linea);
            Cliente cliente = new Cliente(linea.Reloj);
            linea.cliente_actual = cliente;
            generarDecisionCliente(linea);
            switch (linea.eleccion)
            {
                case (int)Utils.eleccion.COMPRA:
                    if (linea.estado_cajero==(int)Utils.cajero.LIBRE)
                    {
                        cliente.estado=(int)Utils.cliente.ESPERANDO_TICKET;
                        linea.estado_cajero=(int)Utils.cajero.OCUPADO;
                        generarTiempoFinTicket(linea);
                    }
                    else
                    {
                        cliente.estado = (int)Utils.cliente.EN_COLA_TICKET;
                        linea.cola_cajero++;
                    }
                    break;
                case (int)Utils.eleccion.SE_SIENTA:
                    cliente.estado=(int)Utils.cliente.UTILIZANDO_MESA;
                    generarTiempoFinUtilizacionMesa(linea, cliente);
                    break;
                case (int)Utils.eleccion.DE_PASO:
                    cliente.estado=(int)Utils.cliente.DEPASO;
                    generarTiempoFinPaseo(linea, cliente);
                    break;
            }
            gridline.clientes.Add(cliente);
            return linea;
        }
        public void generarProximaLlegada(gridline linea)
        {            
            linea.rnd_llegada = -1;
            double suma = 0;            
            for (int i = 0; i < 12; i++) { suma += NumeroRandom.getInstance().NextDouble(); }
            linea.rndn_llegada = (suma - 6) * this.desviacionEstandar + this.promedio;
            linea.proxima_llegada_cliente = linea.Reloj+linea.rndn_llegada;            
        }
        public void generarDecisionCliente(gridline linea)
        {
            Eleccion eleccion = new Eleccion();
            linea.rnd_eleccion = NumeroRandom.getInstance().NextDouble();
            linea.eleccion = eleccion.getPrimeraEleccion(linea.rnd_eleccion*100);
        }
        public void generarTiempoFinTicket(gridline linea)
        {
            linea.fin_ticket = linea.Reloj + this.tCompraTicket;            
        }
        public void generarTiempoFinUtilizacionMesa(gridline linea, Cliente c)
        {
            double a = this.tUtilizacionMesa - tAdicionalUtilizacionMesa;
            double b = this.tAdicionalUtilizacionMesa * 2;
            //linea.fin_utilizacion= linea.Reloj + a + b * NumeroRandom.getInstance().NextDouble();
            double rand = NumeroRandom.getInstance().NextDouble();
            c.rndCliente = rand;
            c.finUsoMesa = linea.Reloj + a + b * rand;
            
        }
        public void generarTiempoFinPaseo(gridline linea, Cliente cliente)
        {
            double a = 18;
            double b = 4;
            double rand = NumeroRandom.getInstance().NextDouble();
            cliente.rndCliente = rand;
            cliente.finPaso = linea.Reloj + a + b * rand;            
        }        
        
    }
}